﻿#region Header
// ------------------------ Licence / Copyright ------------------------
// 
// ScrumTable for Scrum Meeting Support
// Copyright © HSR - Hochschule für Technik Rapperswil
// All Rights Reserved
// 
// Author:
//  Michael Gfeller Silvan Gehrig Patrick Boos
// 
// ---------------------------------------------------------------------
#endregion

#region Usings

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Dynamic;
using System.Windows.Data;
using ScrumTable.BL.DM.DataManagement;
using ScrumTable.Common;
using ScrumTable.Common.EventHandling;
using ScrumTable.UI.ViewModel.Dynamic;

#endregion

namespace ScrumTable.UI.View.WinTouch.Config
{
    /// <summary>
    /// 
    /// </summary>
    public class DynamicValueResolver : IDynamicValueResolver
    {
        #region Properties
        //--------------------------------------------------------------------
        // Properties
        //--------------------------------------------------------------------
         


        #endregion



        #region Methods

        //--------------------------------------------------------------------
        // Methods
        //--------------------------------------------------------------------

        public object GetOtherAttributs(IScrumItem parent)
        {
            return new DynamicCustomFieldWrapper(parent);
        }



        #endregion

       

       
        /// <summary>
        /// Provides a dynamic wrapper class for providing custom fields to the view model. 
        /// </summary>
        public class DynamicCustomFieldWrapper : DynamicObject, INotifyPropertyChanged
        {


            #region Declarations
            //--------------------------------------------------------------------
            // Declarations
            //--------------------------------------------------------------------


            private readonly FastSmartWeakEvent<PropertyChangedEventHandler> _changedEvents = new FastSmartWeakEvent<PropertyChangedEventHandler>();
            private readonly IScrumItem _parent;


            #endregion

            #region Constructors / Destructor
            //--------------------------------------------------------------------
            // Constructors / Destructor
            //--------------------------------------------------------------------

            /// <summary>
            /// Creates a Wrapper class for a ScrumItem. Use this object like a Property
            /// </summary>
            /// <param name="parent"></param>
            public DynamicCustomFieldWrapper(IScrumItem parent)
            {
                PreCondition.AssertNotNull(parent, "parent");
                _parent = parent;
                _parent.PropertyChanged += OnParentChanged;
            }

            #endregion



            #region Methods
            //--------------------------------------------------------------------
            // Methods
            //--------------------------------------------------------------------

            /// <summary>
            /// Gets a value from the warpped item 
            /// return CustomFields.MyField = "Sample";
            /// </summary>
            /// <param name="binder"></param>
            /// <param name="result"></param>
            /// <returns></returns>
            public override bool TryGetMember(GetMemberBinder binder, out object result)
            {
                result = _parent[binder.Name];
                return true;
            }


            /// <summary>
            /// Sets a value into the wrapped item.
            /// Use this method not directly.
            /// CustomFields.MyField = "Sample";
            /// </summary>
            /// <param name="binder"></param>
            /// <param name="value"></param>
            /// <returns></returns>
            public override bool TrySetMember(SetMemberBinder binder, object value)
            {
                _parent[binder.Name] = value;
                OnPropertyChanged(binder.Name);
                return true;
            }



            #endregion DynamicObject overrides

            #region INotifyPropertyChanged

            public event PropertyChangedEventHandler PropertyChanged
            {
                add { _changedEvents.Add(value); }
                remove { _changedEvents.Remove(value); }
            }

            private void OnParentChanged(object sender, PropertyChangedEventArgs e)
            {
                OnPropertyChanged(e.PropertyName);
            }

            private void OnPropertyChanged(string propertyName)
            {
                _changedEvents.Raise(this, new PropertyChangedEventArgs(propertyName));
            }

            #endregion INotifyPropertyChanged
        }
    }
}